package org.mjl.jackson.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * TencentMapUtil
 *
 * @author mjl2020
 */
public class TencentMapUtil {

    /**
     * Tencent地图Key
     */
    private static final String TENCENT_MAP_KEY = "KVXBZ-NZOWV-SANPK-5Y5RF-JXNTQ-BKB4A";


    /**
     * 输入地址返回经纬度
     * https://lbs.qq.com/service/webService/webServiceGuide/webServiceGeocoder
     */
    private static final String TENCENT_MAP_GEO_API = "https://apis.map.qq.com/ws/geocoder/v1/";
    private static ObjectMapper objectMapper = new ObjectMapper();


    public TencentMapUtil() {
    }

    public static Map<String, String> getLonlat(String address) {
        Map<String, String> resultMap = new HashMap<>();

        String url = TENCENT_MAP_GEO_API + "?output=json&key=" + TENCENT_MAP_KEY + "&address=" + address;
        try {
            RestTemplate restTemplate = new RestTemplate();

            String object = restTemplate.getForObject(url, String.class);

            Map map = objectMapper.readValue(object, Map.class);
            System.out.println(map);
            String status = String.valueOf(map.get("status"));
            if ("0".equals(status)) {
                Map<String, Object> result = (Map<String, Object>) map.get("result");
                // 解析到的坐标（GCJ02坐标系）
                Map<String, Object> location = (Map<String, Object>) result.get("location");
                String lng = String.valueOf(location.get("lng"));
                String lat = String.valueOf(location.get("lat"));
                resultMap.put("lon", lng);
                resultMap.put("lat", lat);
                resultMap.put("lonlat", lng + "," + lat);
            }
            resultMap.put("msg", statusCode(status));
            return resultMap;
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    private static final Map<String, String> STATUS_CODE_MAP = new HashMap<>();

    static {
        STATUS_CODE_MAP.put("0", "结果正常");
        // ------------ 配额鉴权相关（非系统错误）
        STATUS_CODE_MAP.put("110", "请求来源未被授权");
        STATUS_CODE_MAP.put("111", "签名验证失败");
        STATUS_CODE_MAP.put("112", "IP未被授权");
        STATUS_CODE_MAP.put("113", "此功能未被授权");
        STATUS_CODE_MAP.put("120", "此key每秒请求量已达到上限");
        STATUS_CODE_MAP.put("121", "此key每日调用量已达到上限");
        STATUS_CODE_MAP.put("160", "sig参数不支持此请求类型");
        STATUS_CODE_MAP.put("161", "sig参数不支持和非object的POST JSON一起使用");
        STATUS_CODE_MAP.put("190", "无效的KEY");
        STATUS_CODE_MAP.put("199", "此key未开启webservice功能");
        // ------------,	参数错误（非系统错误）
        STATUS_CODE_MAP.put("301", "缺少必要字段key");
        STATUS_CODE_MAP.put("311", "key格式错误");
        STATUS_CODE_MAP.put("300", "缺少必要字段");
        STATUS_CODE_MAP.put("306", "缺少参数");
        STATUS_CODE_MAP.put("310", "参数格式错误");
        STATUS_CODE_MAP.put("320", "参数数据类型错误");
        STATUS_CODE_MAP.put("330", "参数长度错误");
        STATUS_CODE_MAP.put("351", "存在不共存的参数");
        STATUS_CODE_MAP.put("324", "get和post中的同一参数值不相同");
        STATUS_CODE_MAP.put("326", "起终点距离过近");
        STATUS_CODE_MAP.put("327", "附近无公交站");
        STATUS_CODE_MAP.put("328", "无可达公交路线");
        STATUS_CODE_MAP.put("329", "无可达火车路线");
        STATUS_CODE_MAP.put("331", "查询条件过长");
        STATUS_CODE_MAP.put("332", "途径点个数超过限制");
        STATUS_CODE_MAP.put("333", "存在无法吸附的坐标点");
        STATUS_CODE_MAP.put("335", "不支持该城市的公交查询");
        STATUS_CODE_MAP.put("341", "缺少keyword（关键词）");
        STATUS_CODE_MAP.put("344", "附近无火车站（公交）");
        STATUS_CODE_MAP.put("347", "查询无结果");
        STATUS_CODE_MAP.put("348", "参数错误");
        STATUS_CODE_MAP.put("364", "是否扩大搜索参数只能为0或1");
        STATUS_CODE_MAP.put("365", "纬度不能超过±90");
        STATUS_CODE_MAP.put("366", "经度不能超过±180");
        STATUS_CODE_MAP.put("373", "起终点距离超长");
        STATUS_CODE_MAP.put("374", "起终点坐标错误");
        STATUS_CODE_MAP.put("375", "局域网IP无法定位");
        STATUS_CODE_MAP.put("377", "提供的起终点无法规划出导航线路");
        STATUS_CODE_MAP.put("378", "提供的起终点无法规划出步行线路");
        STATUS_CODE_MAP.put("379", "提供的起终点无法规划出公交线路");
        STATUS_CODE_MAP.put("380", "坐标类型必须在有坐标的情况下使用");
        STATUS_CODE_MAP.put("382", "IP无法定位");
        STATUS_CODE_MAP.put("384", "提供的起终点无法规划出骑行线路");
        STATUS_CODE_MAP.put("387", "没有对应的POI");
        STATUS_CODE_MAP.put("393", "没有符合条件的数据");
        STATUS_CODE_MAP.put("394", "错误的查询条件");
        STATUS_CODE_MAP.put("395", "传入参数不合法");
        STATUS_CODE_MAP.put("396", "最多支持200个坐标点，且起终点数目乘积最多为625（距离矩阵）");
        STATUS_CODE_MAP.put("397", "一对多最多支持200个坐标点，多对多最多支持25个坐标点且起终点数目乘积最多为625（距离矩阵）");
        STATUS_CODE_MAP.put("399", "查询关键字错误");
        STATUS_CODE_MAP.put("400", "参数无法解码，请对特殊字符在utf8编码下进行urlencode操作");
        STATUS_CODE_MAP.put("402", "提交的数据格式错误，请确认数据是utf8编码，并对特殊字符进行了urlencode处理");
        STATUS_CODE_MAP.put("403", "不被支持的接口转发");
        STATUS_CODE_MAP.put("404", "错误的请求路径");
        STATUS_CODE_MAP.put("405", "请求方法错误，请更正为：GET");
        STATUS_CODE_MAP.put("406", "请求方法错误，请更正为：POST");
        STATUS_CODE_MAP.put("407", "不被支持的请求方法");
        STATUS_CODE_MAP.put("408", "自定义Referer错误");
        // ------------	以下系统错误（服务质量问题）
        STATUS_CODE_MAP.put("500", "后端超时");
        STATUS_CODE_MAP.put("510", "后端服务无法连接");
        STATUS_CODE_MAP.put("520", "后端服务请求失败");
        STATUS_CODE_MAP.put("530", "后端服务返回数据解析失败");
        STATUS_CODE_MAP.put("531", "后端服务报错");
        STATUS_CODE_MAP.put("600", "其他");
        // 注：5xx系列状态码代表系统错误
    }

    private static String statusCode(String status) {
        String result = STATUS_CODE_MAP.get(status);
        return result;
    }

    public static void main(String[] args) {
        System.out.println(getLonlat("北京市海淀区彩和坊路海淀西大街74号"));
        // {status=121, message=此key每日调用量已达到上限}
        // https://lbs.qq.com/dev/console/quota/mine
        // 腾讯账户头像左侧【控制台】->左侧菜单【账户额度】->【Key额度】，第2页【地址解析】，点击【配额分配】按钮填写要使用的key的相应额度。


    }
}
